/**
  ETFDAQ Project
  \class TAMsg
  \brief to print runtime message
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2024-08-11
  \date 2024-08-11 last modified

  \copyright Copyright (c) 2021-2024 IMP-CAS with LGPLv3 LICENSE
*/

#ifndef TAMsg_h
#define TAMsg_h

#include <iostream>
#include <string>
#include <mutex>
#include <cstdint>

using std::string;

class TAMsg{
public:
	TAMsg();
	virtual ~TAMsg();
	/// \note the returned string will be changed at next call of this func
	/// so if you wanna use it in consecutive calls, please immediately use the
	/// result, or store it in a temporary memory before next call
	static const char *Form(const char *fmt, ...); ///< just like sprintf
	static void Info(const char *cname, const char *fmt, ...);
	static void Error(const char *cname, const char *fmt, ...);
	static void Warn(const char *cname, const char *fmt, ...);
	static void Debug(const char *cname, const char *fmt, ...);
	static void ConfigInfo(const char *cname, const char *fmt, ...);
	static void ShowPoint(const char *msg, const double *p, const int len = 3);
	static void Logo(std::ostream &os = std::cout); ///< ETFAna Logo
	static void LOGO(std::ostream &os = std::cout){ Logo(os); } ///< ETFAna Logo
	static void LogoPlain(string &s); ///< plain logo (without color)

	static void SetVerbose(bool opt = true){ kIsVerbose = opt; }
	static void SetSilent(bool opt = true){ kIsSilent = opt; }
	static void SetDebug(bool opt = true){ kIsDebug = opt; }
	static bool IsVerbose(){ return kIsVerbose; }
	static bool IsSilent(){ return kIsSilent; }
	static bool IsDebug(){ return kIsDebug; }

	/// \param isName (true): no comma in the returned string, suitable for path and file name
	static const char *time0(bool isName = false); ///< current time YYYYMMDD_HHMM
	static const char *sec0(bool isName = false); ///< current time YYYYMMDD_HHMMSS
	static const char *secInterval(time_t t0); ///< interval from t0 to now in HH:MM:SS
	static time_t ms(); // in ms
	static time_t sec(){ return ms() / 1000; }
	static time_t ms1(); ///< time w.r.t the program execution time
	static bool Interrupted();
	static bool irp(){ return Interrupted(); }
	static void SetInterrupted();
	static void SetIRP(){ return SetInterrupted(); }
	static int Signal();
	static void ClearSignal();
	static void SetSignal(int s);
	static void Print32(uint32_t d);
	static void Print16(uint16_t d);

protected:
	static char kMsg[512]; ///< a temporary string
	static bool kIsVerbose; ///< to switch On ConfigInfo() method
	static bool kIsSilent; ///< to switch off Info() method
	static bool kIsDebug; ///< to switch On Debug() method
	static bool kIsInterrupted; ///< SIGINT flag defined, triggered by ctrlc
	static int kSignal; ///< used for detecting IRQs from VME controllers

	static std::mutex kMutex, kMutexSignal;
};

#endif
